/*http://dranger.com/ffmpeg/tutorial05.html
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <math.h>


#include <android/bitmap.h>
#include <android/log.h>

#include <jni.h>
#include <pthread.h>

/*local headers*/

#include "helpers.h"
#include "queue.h"
#include "kompr.h"

#define FFMPEG_LOG_LEVEL AV_LOG_DEBUG
#define LOG_LEVEL 2
#define LOG_TAG "Compressor"
#define LOGI(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__);}
#define LOGE(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__);}
#define LOGW(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__);}


#define MEASURE_TIME

#define MSG_SETDATA_DONE 1
#define MSG_CONVERT_DONE 2

#define STREAM_FRAME_RATE 25 /* 25 images/s */

#ifdef MEASURE_TIME
struct timespec render_frame_start, render_frame_stop;

// http://www.guyrutenberg.com/2007/09/22/profiling-code-using-clock_gettime/
struct timespec timespec_diff(struct timespec start, struct timespec end)
{
	struct timespec temp;
	if ((end.tv_nsec-start.tv_nsec)<0) {
		temp.tv_sec = end.tv_sec-start.tv_sec-1;
		temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
	} else {
		temp.tv_sec = end.tv_sec-start.tv_sec;
		temp.tv_nsec = end.tv_nsec-start.tv_nsec;
	}
	return temp;
}
#endif // MEASURE_TIME


/********************************** Internal declarations *****************************************************/
int do_ffmpeg(int argc, char **argv);
/***********************************************************************************************************/
void signal2Java(JNIEnv *env, jobject thiz, int msgID){
	jclass cls = (*env)->GetObjectClass(env, thiz);
	jmethodID mid = (*env)->GetMethodID(env, cls, "handleSignalFromNative", "(I)V");
	if (mid == 0)
	  return;
	(*env)->CallVoidMethod(env, thiz, mid, msgID);
}
/***********************************************************************************************************/

int jni_encode(JNIEnv *env, jobject thiz, jobjectArray strArgs){
	int i, argc = (*env)->GetArrayLength(env, strArgs);
	char **args = NULL;

	args = (char**)malloc(sizeof(char*) * argc);
	for(i=0; i< argc; i++){
		jstring str = (jstring)(*env)->GetObjectArrayElement(env, strArgs, i);
		args[i] = (char*)(*env)->GetStringUTFChars(env, str, NULL);
	}

	if(doTranscode(args[0], args[1]) != 0){
		signal2Java(env, thiz, -10);
		return -10;
	}
	/* Signal to java that done */
	signal2Java(env, thiz, MSG_CONVERT_DONE);
	for(i=0; i< argc; i++){
		jstring str = (jstring)(*env)->GetObjectArrayElement(env, strArgs, i);
		(*env)->ReleaseStringUTFChars(env, str, args[i]);
	}
	return 0;
}
